package org.jeecg.modules.power.util.pack;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.apache.poi.ss.formula.functions.T;
import org.jeecg.modules.power.util.annotation.NullNote;
import org.springframework.beans.BeanUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 与注解 {@link org.jeecg.modules.power.util.annotation.NullNote}组合使用，校验一个实体类中的必填字段是否为空
 * 有字段为空时将放回对应的字段信息
 * @author scw
 * @version v1.0
 * @date 2024-07-08
 */
@Data
public class Pack<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    public Pack(T t){
        this.getMultiplyRuleFieldPack(t);
    }

    public Pack(){}

    /**
     * 代码
     */
    public Integer code;
    /**
     * 校验是否出错
     */
    public boolean isSuccess;
    /**
     * 校验出错时的错误信息
     * 当正确时返回“成功”
     */
    public String message = "成功";
    /**
     * 实体类数据
     */
    public T data;
    /**
     * 多规则数据情况，key为规则名称，即:rules[i]
     */
    public Map<String,Pack<T>> multiplyData;

    /**
     * 错误
     * @param message
     */
    public Pack<T>  error(String message){
        if(message != null) this.message = message;
        this.isSuccess = false;
        return this;
    }

    /**
     * 正确
     * @param data
     */
    public Pack<T> ok(T data){
        this.data = data;
        this.code = 200;
        this.isSuccess = true;
        return this;
    }

    /**
     * 联合注解NullNote 判断注解属性是否为空
     */
    public Pack<T> getFieldTitleMap(T t) {
        List<String> error = new ArrayList<>();
        try {
            Field[] fields = t.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(NullNote.class)) {
                    String cname = field.getAnnotation(NullNote.class).value();
                    field.setAccessible(true);
                    Object value = field.get(t);
                    String msg = String.format("%s为空", cname);
                    if(Objects.equals(value,null))error.add(msg);
                }
            }
            if(error.size() == 0) return this.ok(t);
        } catch (Exception e) {
            return this.error(e.getMessage());
        }
        return this.error(JSONObject.toJSONString(error));
    }


    /**
     * 联合注解NullNote 判断注解属性是否为空
     */
    public Pack<T> getFieldPack(T t,String rule) {
        Pack<T> pack = new Pack<>();
        List<String> error = new ArrayList<>();
        try {
            Field[] fields = t.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(NullNote.class)) {
                    String cname = field.getAnnotation(NullNote.class).value();
                    String rules = field.getAnnotation(NullNote.class).rules();
                    if(rule != null && rule != ""){
                        if(rules.contains(rule)){
                            field.setAccessible(true);
                            Object value = field.get(t);
                            String msg = String.format("%s为空", cname);
                            if(Objects.equals(value,null))error.add(msg);
                        }
                    }else{
                        field.setAccessible(true);
                        Object value = field.get(t);
                        String msg = String.format("%s为空", cname);
                        if(Objects.equals(value,null))error.add(msg);
                    }
                }
            }
            if(error.size() == 0) return pack.ok(t);
        } catch (Exception e) {
            return pack.error(e.getMessage());
        }
        return pack.error(JSONObject.toJSONString(error));
    }


    /**
     * 联合注解NullNote 判断注解属性是否为空
     * ***多规则***
     */
    public Pack<T> getMultiplyRuleFieldPack(T t) {
        /**1、先取到所有的规则*/
        List<String> rules = this.getRules(t);
        /**2、拿到一个全部规则Pack*/
//        Pack<T> pack = new Pack<>();
        BeanUtils.copyProperties(getFieldPack(t,null),this);
        /**
         * 3、定义一个容器
         * 循环处理每个规则情况
          */
        Map<String,Pack<T>> multiplyData = new HashMap<>();
        for(String rule:rules){
            Pack<T> rulePack = getFieldPack(t,rule);
            /**
             * new一个新的，防止当值赋值会同时赋值给之前的
             */
            Pack<T> rp = new Pack<>();
            BeanUtils.copyProperties(rulePack,rp);
            multiplyData.put(rule,rp);
        }
        this.setMultiplyData(multiplyData);
        return this;
    }

    /**
     * 获取T中NullNote的规则
     * @param t
     * @return
     */
    public List<String> getRules(T t){
        List<String> rules = new ArrayList<>();
        try {
            Field[] fields = t.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(NullNote.class)) {
                    String rule = field.getAnnotation(NullNote.class).rules();
                    if(rule != null && rule != "") {
                        List<String> ruleList = Arrays.asList(rule.split(","));
                        rules = Stream.concat(rules.stream(), ruleList.stream())
                                .distinct()
                                .collect(Collectors.toList());
                    }
                }
            }
        } catch (Exception e) {
        }
        return rules;
    }


}
